<template>
  <vxe-table
    ref="erpTable"
    class="erp-table"
    v-bind="$attrs"
    :sync-resize="syncResize"
    :show-overflow="showOverflow"
    :show-header-overflow="showHeaderOverflow"
    :show-footer-overflow="showFooterOverflow"
    :highlight-hover-row="highlightHoverRow"
    :highlight-hover-column="highlightHoverColumn"
    :highlight-current-row="highlightCurrentRow"
    :highlight-current-column="true"
    :row-key="rowKey"
    :auto-resize="autoResize"
    :header-row-style="headerRowStyleCom"
    :header-cell-style="headerCellStyleCom"
    :row-style="rowStyleCom"
    :cell-style="cellStyleCom"
    :footer-row-class-name="footerRowClassName"
    :footer-cell-class-name="footerCellClassName"
    :sort-config="sortConfigCom"
    :resizable="resizable"
    :stripe="stripeCom"
    :tree-config="treeConfigCom"
    :checkbox-config="checkboxConfigCom"
    :custom-config="customConfigCom"
    :menu-config="menuConfigCom"
    :empty-render="emptyRenderCom"
    v-on="$listeners"
    @edit-closed="handleEditClosed"
    @menu-click="handleMenuClick"
    @cell-click="handleCellClick"
  >
    <slot
      slot="empty"
      name="empty"
    />
    <slot
      slot="default"
      name="default"
    />
  </vxe-table>
</template>

<script>
import XEUtils from 'xe-utils';
import {VXETable} from 'vxe-table';
import {parseTime, toast} from "../../../utils";
import clip from '@/utils/clipboard';
const fontSize = document.getElementsByTagName('body')[0].style.getPropertyValue("--font-size");
VXETable.renderer.add('NoData', {
  // 空内容模板
  renderEmpty (h, renderOpts) {
    return [
      <div style="padding: 20px;">
        <i class="iconfont icon-zanwushuju" style="font-size: 50px"></i>
        <div>没有更多数据了</div>
      </div>
    ];
  }
});
VXETable.renderer.add('NoUnitConfig', {
  // 空内容模板
  renderEmpty (h, renderOpts) {
    return [
      <div style="padding: 20px;">
        <div>暂无单位转换配置</div>
      </div>
    ];
  }
});
VXETable.renderer.add('NoPermission', {
  // 空内容模板
  renderEmpty (h, renderOpts) {
    return [
      <div style="padding: 20px;">
        <i class="iconfont icon-zanwuquanxian" style="font-size: 50px"></i>
        <div>暂无访问权限</div>
      </div>
    ];
  }
});
VXETable.formats.mixin({
  // 格式化性别
  formatStatus ({ cellValue, row, column }) {
    return cellValue ? (cellValue == 10 ? '正常' : '停用') : '';
  },
  // 格式化性别
  formatSex ({ cellValue }) {
    return cellValue ? (cellValue === '1' ? '男' : '女') : '';
  },
  // 格式化下拉选项
  formatSelect ({ cellValue }, list, keys) {
    let labelKey = keys && keys.label ? keys.label : 'label';
    let valueKey = keys && keys.value ? keys.value : 'value';
    const item = list.find(item => item[valueKey] == cellValue);
    return item ? item[labelKey] : '';
  },
  // 格式化日期，默认 yyyy-MM-dd HH:mm:ss
  formatDate ({ cellValue }, format) {
    return parseTime(cellValue, format || '{y}-{m}-{d} {h}:{i}:{s}');
  },
  // 四舍五入金额，每隔3位逗号分隔，默认3位数
  formatAmount ({ cellValue }, digits = 3) {
    return !cellValue ? '' : XEUtils.commafy(XEUtils.toNumber(cellValue), { digits });
  },
  // 格式化银行卡，默认每4位空格隔开
  formatBankcard ({ cellValue }) {
    return XEUtils.commafy(XEUtils.toString(cellValue), { spaceNumber: 4, separator: ' ' });
  },
  // 四舍五入,默认两位数
  formatFixedNumber ({ cellValue }, digits = 2) {
    return !cellValue ? '' : XEUtils.toFixed(XEUtils.round(cellValue, digits), digits);
  },
  // 向下舍入,默认两位数
  formatCutNumber ({ cellValue }, digits = 2) {
    return XEUtils.toFixed(XEUtils.floor(cellValue, digits), digits);
  },
  // 转换 moment 类型为字符串
  toMomentString ({ cellValue }, format) {
    return cellValue ? cellValue.format(format) : '';
  },
  // 转换 状态
  setform( { cellValue } ) {
    return cellValue ? (cellValue == 10 ? '正常' : '停用') : '';
  },
  // 转换 会计科目类型
  formatType({ cellValue, row, column }) {
    return row.typeShowText
  },
  // 转换 品牌
  formatBrandId({ cellValue, row, column }) {
    return row.brandIdShowText
  },
  // 转换 库存类型
  formatSaveType({ cellValue, row, column }) {
    return row.saveTypeShowText
  },
  // 转换 计价方法
  formatMoneyCountType({ cellValue, row, column }) {
    return row.moneyCountTypeShowText
  },
  // 转换 计算方式
  formatCalMethod({ cellValue, row, column }) {
    return row.calMethodShowText
  },
  // 转换 默认仓库
  formatDefaultStockId({ cellValue, row, column }) {
    return row.defaultStockIdShowText
  },
  // 转换 默认货位
  formatDefaultStockLocId({ cellValue, row, column }) {
    return row.defaultStockLocIdShowText
  },
  // 转换 物料分类
  formatDictItemIdSubClass({ cellValue, row, column }) {
    return row.dictItemIdSubClassShowText
  },
  // 转换 材质成分
  formatElementId({ cellValue, row, column }) {
    return row.elementIdShowText
  },
  // 转换 物料类型
  formatMaterialTypeId({ cellValue, row, column }) {
    return row.materialTypeIdShowText
  },
  // 转换 原料特性分类
  formatRawMaterialFeatureClassId({ cellValue, row, column }) {
    return row.rawMaterialFeatureClassIdShowText
  },
  // 转换 默认的销售单位
  formatSellUnitId({ cellValue, row, column }) {
    return row.sellUnitIdShowText
  },
  // 转换 物料模块—状态
  formatBasMaterialStatus({ cellValue, row, column }) {
    return row.statusShowText
  },
  // 转换 库存类型
  formatStockType({ cellValue, row, column }) {
    return row.stockTypeShowText
  },
  // 转换 机型
  formatMachineTypeId({ cellValue, row, column }) {
    return row.machineTypeIdShowText
  },
  // 转换 单位组
  formatDictUnitGroup({ cellValue, row, column }) {
    return row.dictUnitGroupShowText
  },
  // 转换 主计量单位
  formatMainUnitId({ cellValue, row, column }) {
    return row.mainUnitIdShowText
  },
  // 转换 从计量单位
  formatSubUnitId({ cellValue, row, column }) {
    return row.subUnitIdShowText
  },
  // 转换 捻向
  formatTwistDirId({ cellValue, row, column }) {
    return row.twistDirIdShowText
  },
  // 转换 仓库类型
  formatStockTypeId ({ cellValue, row, column }) {
    return row.stockTypeIdShowText
  },
  // 转换 是否是系统
  formatIsSystem ({ cellValue, row, column }) {
    return cellValue == 1 ? '是' : '否';
  },
  // 转换 所属公司
  formatComId ({ cellValue, row, column }) {
    return row.comIdShowText
  },
  // 转换 出入库类型
  formatInOutType ({ cellValue, row, column }) {
    return cellValue == 10 ? '入库' : (cellValue == 20 ? '出库' : '');
  },
  // 转换 对象范围集
  formatObjTypeIds ({ cellValue, row, column }) {
    return row.objTypeIdsShowText
  },
  // 转换 源单类型集
  formatSourceTypeIds ({ cellValue, row, column }) {
    return row.sourceTypeIdsShowText
  },
  // 转换 仓库
  formatStockId ({ cellValue, row, column }) {
    return row.stockIdShowText
  },
  // 转换 对应出入库类型
  formatSysInOutId ({ cellValue, row, column }) {
    return row.sysInOutIdShowText
  },
});
/**
   * 封装表格[vxe-table](https://xuliangzhan_admin.gitee.io/vxe-table/v2/#/table/api)
   */
export default {
  name: "ErpTable",
  props: {
    /**
       * 自动跟随某个属性的变化去重新计算表格，和手动调用 recalculate 方法是一样的效果（对于通过某个属性来控制显示/隐藏切换时可能会用到）
       * @public
       */
    syncResize: {
      type: [Boolean, String, Number],
      default: null
    },
    /**
       * 表格是否有权限
       * @public
       */
    listPermission: {
      type: Boolean,
      default: false,
    },
    /**
       * 设置所有内容过长时显示为省略号（如果是固定列建议设置该值，提升渲染速度）
       * @public
       */
    showOverflow: {
      type: Boolean,
      default: true,
    },
    /**
       * 自动监听父元素的变化去重新计算表格（对于父元素可能存在动态变化、显示隐藏的容器中、列宽异常等场景中的可能会用到）
       * @public
       */
    autoResize: {
      type: Boolean,
      default: true,
    },
    /**
       * 设置表头所有内容过长时显示为省略号
       * @public
       */
    showHeaderOverflow: {
      type: Boolean,
      default: true,
    },
    /**
       * 设置表尾所有内容过长时显示为省略号
       * @public
       */
    showFooterOverflow: {
      type: Boolean,
      default: true,
    },
    /**
       * 鼠标移到行是否要高亮显示
       * @public
       */
    highlightHoverRow: {
      type: Boolean,
      default: true,
    },
    /**
       * 是否要高亮当前行
       * @public
       */
    highlightCurrentRow: {
      type: Boolean,
      default: true,
    },
    /**
       * 鼠标移到列是否要高亮显示
       * @public
       */
    highlightHoverColumn: {
      type: Boolean,
      default: false,
    },
    /**
       * 是否需要为每一行的 VNode 设置 key 属性（非特殊情况下没必要设置）
       * @public
       */
    rowKey: {
      type: Boolean,
      default: true,
    },
    /**
       * 给表头行附加样式
       * @public
       */
    headerRowStyle: {
      type: [Object, Function],
      default: () => {}
    },
    /**
       * 给表头单元格附加样式
       * @public
       */
    headerCellStyle: {
      type: [Object, Function],
      default: () => {}
    },
    /**
       * 给行附加样式，也可以是函数
       * @public
       */
    rowStyle: {
      type: [Object, Function],
      default: () => {}
    },
    /**
       * 给表尾的行附加 className
       * @public
       */
    footerRowClassName: {
      type: [String, Function],
      default: ''
    },
    /**
       * 给表尾的单元格附加 className
       * @public
       */
    footerCellClassName: {
      type: [String, Function],
      default: ''
    },
    /**
       * 排序配置项
       * @public
       */
    sortConfig: {
      type: Object,
      default: () => {}
    },
    /**
       * 所有的列是否允许拖动列宽调整大小
       * @public
       */
    resizable: {
      type: Boolean,
      default: true
    },
    /**
       * 是否带有斑马纹（需要注意的是，在可编辑表格场景下，临时插入的数据不会有斑马纹样式）
       * @public
       */
    stripe: {
      type: Boolean,
      default: true
    },
    /**
       * 是否是树表格
       * @public
       */
    isTree: {
      type: Boolean,
      default: false
    },
    /**
       * 树形结构配置项（不能用于虚拟滚动）
       * @public
       */
    treeConfig: {
      type: Object,
      default: () => {}
    },
    /**
       * 复选框配置项
       * @public
       */
    checkboxConfig: {
      type: Object,
      default: () => {}
    },
    /**
       * 列是否可选
       * @public
       */
    itemSelectable: {
      type: Function,
      default: null
    },
    /**
       * 自定义列配置项
       * @public
       */
    customConfig: {
      type: Object,
      default: () => {}
    },
    /**
       * 快捷菜单配置项
       * @public
       */
    menuConfig: {
      type: Object,
      default: () => {
        return {};
      }
    },
    /**
       * 空渲染
       * @public
       */
    emptyRender: {
      default () {
        return {};
      }
    },
    /**
       * 只对 menu-config 配置时有效，当点击快捷菜单时会触发该事件
       * @public
       */
    menuClick: {
      type: Function,
      default: null
    },
    /**
     * 接收的表格数据
     * @public
     */
  
  },
  computed: {
    emptyRenderCom () {
      const defaultConfig = {name: !this.listPermission ? 'NoPermission' : 'NoData'};
      return Object.assign(defaultConfig, this.emptyRender);
    },
    headerRowStyleCom () {
      let defaultConfig = {backgroundColor: '#F8FBFF', height: '30px'};
      if (this.headerRowStyle) {
        defaultConfig = Object.assign(defaultConfig, this.headerRowStyle);
      }
      return defaultConfig;
    },
    headerCellStyleCom () {
      let defaultConfig = {
        padding: '6px 0',
        fontSize: fontSize,
        height: '30px'
      };
      if (this.headerCellStyle) {
        defaultConfig = Object.assign(defaultConfig, this.headerCellStyle);
      }
      return defaultConfig;
    },
    menuConfigCom () {
      let defaultConfig = {
        enable: false,
        className: 'erp-menus',
        header: {
        },
        body: {
          options: [
            [
              { code: 'copy', name: '复制', prefixIcon: 'el-icon-document-copy', className: 'my-copy-item' }
            ],
          ]
        },
        footer: {
        }
      };
      // return Object.assign(defaultConfig, this.menuConfig)
      return this.menuConfig;
    },
    rowStyleCom () {
      let height = '36px';
      if (fontSize === '12px') {
        height = '26px';
      } else if (fontSize === '14px') {
        height = '36px';
      } else if (fontSize === '16px') {
        height = '40px';
      } else if (fontSize === '18px') {
        height = '48px';
      }
      let defaultConfig = {height: height};
      if (this.rowStyle) {
        defaultConfig = Object.assign(defaultConfig, this.rowStyle);
      }
      return defaultConfig;
    },
    cellStyleCom () {

      let height = '36px';
      if (fontSize === '12px') {
        height = '26px';
      } else if (fontSize === '14px') {
        height = '36px';
      } else if (fontSize === '16px') {
        height = '40px';
      } else if (fontSize === '18px') {
        height = '48px';
      }
      let defaultConfig = {
        height: height,
        fontSize: fontSize
      };

      if (this.cellStyle) {
        defaultConfig = Object.assign(defaultConfig, this.cellStyle);
      }
      return defaultConfig;
    },
    sortConfigCom () {
      let defaultConfig = {remote: true, trigger: "cell"};
      if (this.sortConfig) {
        defaultConfig = Object.assign(defaultConfig, this.sortConfig);
      }
      return defaultConfig;
    },
    stripeCom () {
      if (this.isTree) {
        return undefined;
      }
      return this.stripe === undefined ? true : this.stripe;
    },
    treeConfigCom () {
      if (!this.isTree){
        return undefined;
      }
      let defaultConfig = {
        "expandAll": true,
        "indent": 20,
        "line": true
      };
      let userConfig = this.treeConfig;
      return Object.assign(defaultConfig, userConfig);
    },
    checkboxConfigCom () {
      let defaultCheckboxConfig = {
        highlight: !this.isTree,
        trigger: 'default'
      };
      if (!this.isTree){
        defaultCheckboxConfig.range = false;
      }
      if (this.itemSelectable) {
        defaultCheckboxConfig.checkMethod = ({row}) => {
          let fuc = this.itemSelectable;
          return fuc(row);
        };
      }
      let userCheckboxConfig = this.checkboxConfig;
      return Object.assign(defaultCheckboxConfig, userCheckboxConfig);
    },
    customConfigCom () {
      let defaultConfig = {
        storage: {
          visible: false,
          resizable: false,
        }
      };
      let userConfig = this.customConfig;
      return Object.assign(defaultConfig, userConfig);

    }
  },
  methods: {
    /**
       * 重新计算表格，如果传 true 则进行完整计算（对于某些特殊场景可能会用到，比如隐藏的表格、重新计算列宽...等）
       * @private
       * @param refull
       */
    recalculate (refull) {
      this.$refs.erpTable.recalculate(refull);
    },
    /**
       * @private
       * @param menu
       * @param row
       * @param column
       * @param event
       */
    handleMenuClick ({menu, row ,column}, event) {
      if (this.menuClick) {
        this.menuClick({menu, row ,column}, event);
      } else {
        switch (menu.code) {
        case 'copy':
          if (row && column) {
            if (clip(row[column.property], event)) {
              console.log(row);
            }
          }
          break;
        default:
        }
      }
    },
    handleCellClick ({row, rowIndex, $rowIndex, column, columnIndex, $columnIndex, triggerRadio, triggerCheckbox}, event) {
      this.$bus.$emit("cellClick", {row, rowIndex, $rowIndex, column, columnIndex, $columnIndex});
    },
    handleEditClosed({row, rowIndex, $rowIndex, column, columnIndex, $columnIndex}, event) {
      let table = this.$refs['erpTable'].getTableData().tableData;
      this.$bus.$emit("editClosed", {table, row, rowIndex, $rowIndex, column, columnIndex, $columnIndex});
    }
  }
};
</script>

<style lang="scss" scoped>

  ::v-deep{
    .vxe-header--column.col--ellipsis.col--checkbox>.vxe-cell .vxe-cell--title{
      overflow: visible;
    }
    $tableStripeBgColor: #f8fbff;
    .vxe-table .vxe-body--row.row--stripe, .vxe-table--render-default .vxe-body--row.row--stripe{
      background-color: $tableStripeBgColor;
      &.row--checked{
        background-color: #fff3e0;
      }
      &.row--current{
        background-color: #e6f7ff;
      }
    }

  }

</style>
